package edu.vt.ece.main;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import edu.vt.ece.util.AVLTree;
import edu.vt.ece.util.ConcurrentAVLTree;

/**
 * This is the main testing class for the AVL tree. You can use this to add,
 * remove and test to see if a specific key is in the tree.
 * 
 * 
 * @author Jeremy & Brian
 */
public class Tester {

	private static int THREAD_COUNT = 1;
	private static int LOOP_COUNT = 50000;
	public static int ADD_PROBABILITY = 20;
	public static int CONTAINS_PROBABILITY = 80;
	public static int REMOVE_PROBABILITY = 0;
	public static boolean DEBUG_MODE = false;
	private static boolean courseGrainLock = false;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		if(100!=(ADD_PROBABILITY + CONTAINS_PROBABILITY + REMOVE_PROBABILITY)) {
			System.out.println("Error: Invalid probabilities");
			return;
		}
		
		AVLTree tree = new AVLTree();
		ConcurrentAVLTree cTree = new ConcurrentAVLTree();
		
		showValidActions();
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

		boolean working = true;
		int value;
		while (working) {
			// read in values from the command line in the style 'a' for add;
			// 'r' for remove; 'c' for contains followed by a number
			try {
				String userInput = reader.readLine();
				if (userInput.startsWith("a ")) {
					value = getKey(userInput);
					if(!tree.add(value)) {
						System.out.println("Failed to add " + value);
					}
				} else if (userInput.startsWith("c ")) {
					value = getKey(userInput);
					if (tree.contains(value) != null)
						System.out.println("Tree does contain " + value);
					else
						System.out.println("Tree does not contain " + value);
				} else if (userInput.startsWith("r ")) {
					value = getKey(userInput);
					if(tree.remove(value)) {
						System.out.println("Successfully removed " + value);
					} else {
						System.out.println("Failed to remove " + value);
					}
				} else if (userInput.startsWith("p")) {
					tree.printTree();
				} else if (userInput.startsWith("zi")) {
					working = false;
					System.out.print("Enter number of threads to use: ");
					int threadCount = Integer.parseInt(reader.readLine());

					System.out.print("Enter number of thread operations to run: ");
					int loopCount = Integer.parseInt(reader.readLine());

					System.out.print("Use the course grain locking tree? [Y/n] ");
					String concurrentTree = reader.readLine();
					courseGrainLock = concurrentTree.matches("|Y|y");
					
					System.out.print("Print out debug statements? [y/N] ");
					String debugString = reader.readLine();
					DEBUG_MODE = !debugString.matches("|N|n");

					for (int i = 0; i < threadCount; i++)
					{
						if (courseGrainLock)
						{
							new AVLThread(loopCount, tree, DEBUG_MODE).start();
						}
						else
						{
							new AVLThread(loopCount, cTree, DEBUG_MODE).start();
						}
					}

				}
				else if (userInput.startsWith("z"))
				{
					working = false;
					for (int i = 0; i < THREAD_COUNT; i++)
					{
						if (courseGrainLock)
						{
							new AVLThread(LOOP_COUNT, tree, DEBUG_MODE).start();
						}
						else
						{
							new AVLThread(LOOP_COUNT, cTree, DEBUG_MODE).start();
						}
					}

				}
				else {
					showValidActions();
				}
			} catch (Exception e) {
				e.printStackTrace();
				working = false;
			}
		}
	}

	private static int getKey(String userInput) {
		return Integer.parseInt(userInput.substring(2, userInput.length()));
	}

	private static void showValidActions() {
		System.out.println("User Syntax Reference: [action] [int-value].");
		System.out.println("\tValid actions:");
		System.out.println("\t\t a - add");
		System.out.println("\t\t c - contains");
		System.out.println("\t\t p - print (does not require an int-value)");
		System.out.println("\t\t r - remove");
		System.out.println("\t\t z - multi thread test");
		System.out.println("\t\t zi - interactive multi-thread test");
	}

}
